package com.lnsf.bookstore.system.schedule.controller;

import com.github.pagehelper.PageInfo;
import com.lnsf.bookstore.common.dto.ApiConstants;
import com.lnsf.bookstore.common.dto.ResultDto;
import com.lnsf.bookstore.common.dto.ResultFailDto;
import com.lnsf.bookstore.common.dto.ResultSuccessDto;
import com.lnsf.bookstore.system.schedule.service.ScheduleJobService;
import com.lnsf.bookstore.system.schedule.vo.ScheduleJob;

import javafx.beans.binding.ObjectExpression;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 定时任务
 *
 */
@Controller
@RequestMapping("/schedule")
public class ScheduleJobController {

    private static final Logger log = LoggerFactory.getLogger(ScheduleJobController.class);

    @Autowired
    private ScheduleJobService scheduleJobService;

    @RequestMapping("/v_list.do")
    public String v_list(){
        return "admin/schedule/schedule";
    }

    @RequestMapping("/o_list.do")
    @ResponseBody
    public Object o_list(ScheduleJob scheduleJob, ModelMap modelMap){
        PageInfo<ScheduleJob> pageInfo =  scheduleJobService.queryList(scheduleJob);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("page",pageInfo);
        return map;

    }

    @RequestMapping("/add.do")
    @ResponseBody
    public ResultDto add( @RequestBody ScheduleJob scheduleJob, ModelMap modelMap){
        try {
            if (!CronExpression.isValidExpression(scheduleJob.getCronExpression())) {
                return new ResultFailDto(   "任务表达式不正确！，请校验");
            }
            scheduleJobService.add(scheduleJob);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return new ResultFailDto(e.getMessage());
        }
        return new ResultSuccessDto(ApiConstants.SUCCESS_MSG);
    }

    @RequestMapping(value = "/info.do", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Object v_edit(@RequestBody ScheduleJob scheduleJob, ModelMap modelMap, HttpServletRequest request) {
        Map<String,Object> map = new HashMap<String,Object>();
        try {
            scheduleJob.setGroup(new String(scheduleJob.getGroup().getBytes("ISO-8859-1")));
            scheduleJob.setName(new String(scheduleJob.getName().getBytes("ISO-8859-1")));
            ScheduleJob jobDetails = scheduleJobService.getJobDetails(scheduleJob.getName(), scheduleJob.getGroup());
            if (jobDetails != null) {

            }
            map.put("scheduleJob", jobDetails);
        } catch (RuntimeException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return map;
    }


    @RequestMapping("/update.do")
    @ResponseBody
    public ResultDto update( @RequestBody ScheduleJob scheduleJob, ModelMap modelMap){
        try {
            if (!CronExpression.isValidExpression(scheduleJob.getCronExpression())) {
                return new ResultFailDto(   "任务表达式不正确！，请校验");
            }
            if (!scheduleJobService.checkExist(scheduleJob.getName(), scheduleJob.getGroup())) {
                return new ResultFailDto("更新失败，原因：任务不存在！");
            }
            scheduleJobService.update(scheduleJob);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return new ResultFailDto("更新失败，原因：任务类不存在");
        } catch (SchedulerException e) {
            e.printStackTrace();
            return new ResultFailDto("更新失败，原因：" + e.getMessage());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return new ResultFailDto("更新失败，原因：" + e.getMessage());
        }
        return new ResultSuccessDto(ApiConstants.SUCCESS_MSG);
    }

    @RequestMapping("/run.do")
    @ResponseBody
    public ResultDto run(@RequestBody ScheduleJob scheduleJob, ModelMap modelMap){
        return job(scheduleJob, "立即执行任务", sj -> sj.runNow(scheduleJob.getName(), scheduleJob.getGroup()));
    }

    @ResponseBody
    @RequestMapping(value = "/start.do")
    public ResultDto start(@RequestBody ScheduleJob scheduleJob) {
        return job(scheduleJob, "启动任务", sj -> sj.resume(scheduleJob.getName(), scheduleJob.getGroup()));
    }

    @ResponseBody
    @RequestMapping(value = "/stop.do")
    public ResultDto stop(@RequestBody ScheduleJob scheduleJob) {
        return job(scheduleJob, "暂停任务", st -> st.pause(scheduleJob.getName(), scheduleJob.getGroup()));
    }

    @ResponseBody
    @RequestMapping(value = "/schedule/delete.do")
    public ResultDto deleteOne(@RequestBody  ScheduleJob scheduleJob) {
        try {
            scheduleJobService.delete(scheduleJob.getName(),scheduleJob.getGroup());
        } catch (RuntimeException e) {
            e.printStackTrace();
            return new ResultFailDto("删除失败，原因：" + e.getMessage());
        }
        return new ResultSuccessDto(ApiConstants.SUCCESS_MSG);
    }

    private ResultDto job(ScheduleJob scheduleJob, String info, Consumer<ScheduleJobService> consumer) {
        //logService.add(info + scheduleJob.getName());
        if (StringUtils.isBlank(scheduleJob.getGroup()) || StringUtils.isBlank(scheduleJob.getName())) {
            return new ResultFailDto(info + "失败，原因：组名称或任务名称错误");
        }
        try {
            if (scheduleJobService.checkExist(scheduleJob.getName(), scheduleJob.getGroup())) {
                consumer.accept(scheduleJobService);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultFailDto(info + "失败，原因：" + e.getMessage());
        }
        return new ResultSuccessDto(ApiConstants.SUCCESS_MSG);
    }

}
